﻿using System;
using System.Collections.Generic;
using System.IO;
using System.IO.IsolatedStorage;
using System.Windows;
using System.Windows.Browser;

namespace Helper
{
    [ScriptableType]
    public class LoggerService : ServiceBase
    {
        private IsolatedStorageFile storage;

        public static LoggerService Current { get; set; }

        private bool _isActive;
        [ScriptableMember]
        public bool IsActive
        {
            get { return this._isActive; }
            private set { base.SetPropertyValue<bool>(ref this._isActive, value, () => this.IsActive); }
        }

        private string _logEntryFormat = "{0:HH:mm:ss} {1,-20} {2}";
        [ScriptableMember]
        public string LogEntryFormat
        {
            get { return this._logEntryFormat; }
            set { base.SetPropertyValue<string>(ref this._logEntryFormat, value, () => this.LogEntryFormat); }
        }

        private string _logFilePathFormat = "{0:yyyyMMdd}.log";
        [ScriptableMember]
        public string LogFilePathFormat
        {
            get { return this._logFilePathFormat; }
            set { base.SetPropertyValue<string>(ref this._logFilePathFormat, value, () => LogFilePathFormat, this.TestLog); }
        }

        [ScriptableMember]
        public void ClearLogs()
        {
            try
            {
                this.DeleteRecursive(this.storage, "");
            }
            catch (Exception exception)
            {
                base.ReportErrorToDOM(exception);
            }
        }

        private void DeleteRecursive(IsolatedStorageFile storage, string path)
        {
            Exception exception;
            foreach (string str in storage.GetFileNames(Path.Combine(path, "*.*")))
            {
                try
                {
                    storage.DeleteFile(Path.Combine(path, str));
                }
                catch (Exception exception1)
                {
                    exception = exception1;
                    base.ReportErrorToDOM(exception);
                }
            }
            foreach (string str2 in storage.GetDirectoryNames(Path.Combine(path, "*")))
            {
                this.DeleteRecursive(storage, Path.Combine(path, str2));
            }
            if (!string.IsNullOrEmpty(path))
            {
                try
                {
                    storage.DeleteDirectory(path);
                }
                catch (Exception exception2)
                {
                    exception = exception2;
                    base.ReportErrorToDOM(exception);
                }
            }
        }

        private IsolatedStorageFileStream GetStream()
        {
            string str = string.Format(this.LogFilePathFormat, DateTime.Now);
            if (string.IsNullOrEmpty(str))
            {
                throw new Exception("Empty log path");
            }
            string directoryName = Path.GetDirectoryName(str);
            if (!this.storage.DirectoryExists(directoryName))
            {
                this.storage.CreateDirectory(directoryName);
            }
            if (!this.storage.FileExists(str))
            {
                using (IsolatedStorageFileStream stream = this.storage.CreateFile(str))
                {
                    stream.Flush();
                    stream.Close();
                }
            }
            return this.storage.OpenFile(str, FileMode.Append);
        }

        [ScriptableMember]
        public void Log(string message)
        {
            this.Log(message, string.Empty);
        }

        [ScriptableMember]
        public void Log(string message, string key)
        {
            this.LogText(string.Format(this.LogEntryFormat, DateTime.Now, key, message) + Environment.NewLine);
        }

        private void LogText(string text)
        {
            if (this.IsActive)
            {
                this.WriteString(text);
            }
        }

        protected override void StartService(ApplicationServiceContext context)
        {
            try
            {
                this.storage = IsolatedStorageFile.GetUserStoreForSite();
                Dictionary<string, string> applicationInitParams = context.ApplicationInitParams;
                if (applicationInitParams.ContainsKey("LogEntryFormat"))
                {
                    this.LogEntryFormat = applicationInitParams["LogEntryFormat"];
                }
                if (applicationInitParams.ContainsKey("LogFilePathFormat"))
                {
                    this.LogFilePathFormat = applicationInitParams["LogFilePathFormat"];
                }
                Current = this;
            }
            catch (Exception exception)
            {
                base.ReportErrorToDOM(exception);
            }
            HtmlPage.RegisterScriptableObject("Logger", this);
        }

        protected override void StopService()
        {
            if (this.storage != null)
            {
                this.storage.Dispose();
            }
            Current = null;
        }

        private void TestLog()
        {
            this.IsActive = false;
            try
            {
                using (IsolatedStorageFileStream stream = this.GetStream())
                {
                    stream.Flush();
                    stream.Close();
                }
                this.IsActive = true;
            }
            catch (Exception exception)
            {
                base.ReportErrorToDOM(exception);
            }
        }

        private void WriteString(string message)
        {
            try
            {
                using (IsolatedStorageFileStream stream = this.GetStream())
                {
                    using (StreamWriter writer = new StreamWriter(stream))
                    {
                        writer.Write(message);
                    }
                }
            }
            catch (Exception exception)
            {
                base.ReportErrorToDOM(exception);
            }
        }
    }
}

